﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

using Google.GData.Client;

namespace LINQToolKit.GData
{
    /// <summary>
    /// helper class for generating the oauth signature and post header
    /// </summary>
    /// <remarks>
    /// This framework is under the GNU licence and Creative Commons 3.0.
    /// You can also get a copy of the source code from google code
    /// <see cref="http://linqtodouban.googlecode.com/svn/trunk/"/>.
    /// For more information and further support, please contact with kevin (chwkai@gmail.com)
    /// </remarks>
    public static class Auths
    {
        /// <summary>
        /// generate the url with the OAuth signature
        /// </summary>
        /// <param name="url"></param>
        /// <param name="httpMethod"></param>
        /// <param name="consumerKey"></param>
        /// <param name="consumerKeySecret"></param>
        /// <param name="accessToken"></param>
        /// <param name="accessTokenSecret"></param>
        /// <returns></returns>
        public static Uri Sign(
            Uri url, 
            string httpMethod,
            string consumerKey, 
            string consumerKeySecret, 
            string accessToken, 
            string accessTokenSecret
            )
        {
            string normalizedUrl = string.Empty;
            string normalizedParameter = string.Empty;

            OAuthBase auth = new OAuthBase();
            string signature = auth.GenerateSignature(
                url,
                consumerKey,
                consumerKeySecret,
                accessToken,
                accessTokenSecret,
                httpMethod,
                auth.GenerateTimeStamp(),
                auth.GenerateNonce(),
                OAuthBase.SignatureTypes.HMACSHA1,
                out normalizedUrl,
                out normalizedParameter
                );

            string template = "{0}?{1}&oauth_signature={2}";
            string result = string.Format(
                template, normalizedUrl, normalizedParameter, HttpUtility.UrlEncode(signature));
            return new Uri(result);
        }

        /// <summary>
        /// Generate the post header with OAuth signature
        /// </summary>
        /// <param name="url"></param>
        /// <param name="httpMethod"></param>
        /// <param name="consumerKey"></param>
        /// <param name="consumerKeySecret"></param>
        /// <param name="accessToken"></param>
        /// <param name="accessTokenSecret"></param>
        /// <returns></returns>
        public static string GetAuthHeader(
            Uri url,
            string httpMethod,
            string consumerKey,
            string consumerKeySecret, 
            string accessToken, 
            string accessTokenSecret
            )
        {
            var auth = new OAuthBase();
            var normalizedUrl = string.Empty;
            var normalizedParameter = string.Empty;
            var timeStamp = auth.GenerateTimeStamp();
            var nonce = auth.GenerateNonce();

            string signature = auth.GenerateSignature(
                url,
                consumerKey,
                consumerKeySecret,
                accessToken,
                accessTokenSecret,
                httpMethod,
                timeStamp,
                nonce,
                OAuthBase.SignatureTypes.HMACSHA1,
                out normalizedUrl,
                out normalizedParameter
                );

            StringBuilder oauthHeader = new StringBuilder();
            oauthHeader.AppendFormat("OAuth realm=\"\", oauth_consumer_key={0}, ", consumerKey);
            oauthHeader.AppendFormat("oauth_nonce={0}, ", nonce);
            oauthHeader.AppendFormat("oauth_timestamp={0}, ", timeStamp);
            oauthHeader.AppendFormat("oauth_signature_method={0}, ", "HMAC-SHA1");
            oauthHeader.AppendFormat("oauth_version={0}, ", "1.0");
            oauthHeader.AppendFormat("oauth_signature={0}, ", signature);
            oauthHeader.AppendFormat("oauth_token={0}", accessToken);

            return oauthHeader.ToString();
        }
    }
}
